/**
 * 
 */
package com.sip.scanadapter.domainparsers;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.namespace.QName;

import com.sip.dbadapter.dao.domain.ApiDefinition;
import com.sip.dbadapter.dao.domain.ConsumeType;
import com.sip.dbadapter.dao.domain.ProduceType;
import com.sip.dbadapter.dao.domain.ScanTypeRest;
import com.sip.scanadapter.common.StratergyType;
import com.sun.research.ws.wadl.Application;
import com.sun.research.ws.wadl.Doc;
import com.sun.research.ws.wadl.Grammars;
import com.sun.research.ws.wadl.Method;
import com.sun.research.ws.wadl.Param;
import com.sun.research.ws.wadl.Representation;
import com.sun.research.ws.wadl.Resource;
import com.sun.research.ws.wadl.Resources;
import com.sun.research.ws.wadl.Response;

/**
 * @author Dhanushka Ariyasingha.
 * 
 */
public class ApiDefinitionParser implements Parser<Set<ApiDefinition>, Application> {

	private Set<ApiDefinition> apiDefinitionSet = new HashSet<ApiDefinition>();

	private StringBuilder urlBuilder = new StringBuilder();

	public ApiDefinitionParser() {
		apiDefinitionSet = new HashSet<ApiDefinition>();
	}


	public Set<ApiDefinition> parser(final Application application) {
		// TODO Auto-generated method stub

		generateDomainCollection(application);

		return apiDefinitionSet;
	}

	private void generateDomainCollection(final Application application) {

		final List<Resources> resourceList = application.getResources();
		collectServiceComponent(resourceList);

	}

	private void collectServiceComponent(final List<Resources> resourceList) {

		for (final Resources resources : resourceList) {
			final List<Resource> subResourceList = resources.getResource();
			collectServiceInfo(subResourceList);
		}

	}

	private void collectServiceInfo(final List<Resource> subResourceList) {

		for (final Resource resource : subResourceList) {

			final String resourcePath = resource.getPath();
			System.out.println("Service Path:" + resourcePath);
			urlBuilder.append(resourcePath);

			collectServiceMethodInfo(resource);

			urlBuilder.delete(0, urlBuilder.length());
		}
	}

	private void collectServiceMethodInfo(final Resource resource) {

		final List<Object> methodOrResourceList1 = resource.getMethodOrResource();

		for (Object object : methodOrResourceList1) {

			if (object instanceof Resource) {

				final Resource serviceResource = (Resource) object;

				collectServiceMethodDefinitionInfo(serviceResource);
				
			} else if (object instanceof Method) {

				final Method method = (Method) object;
				
				final ApiDefinition apiDefDomain = new ApiDefinition();
				final String packageHierachy = resource.getPath();

				apiDefDomain.setPackageHierachy(packageHierachy);
				System.out.println("Package Hierachy String :" + apiDefDomain.getPackageHierachy());

				collectMethodInfo(apiDefDomain, method);

				apiDefDomain.setScanType(Integer.parseInt(StratergyType.STRATERGY_ID_REST));
				apiDefinitionSet.add(apiDefDomain);
			}
		}
	}

	private void collectServiceMethodDefinitionInfo(final Resource serviceResource) {

		final List<Object> methodOrResourceList2 = serviceResource.getMethodOrResource();
		System.out.println("Service Method:" + serviceResource.getPath());

		for (Object methodObj : methodOrResourceList2) {

			if (methodObj instanceof Method) {

				final ApiDefinition apiDefDomain = new ApiDefinition();
				final String packageHierachySecondPart = serviceResource.getPath().subSequence(0, 1).equals("/") ? serviceResource.getPath() : "/"	+ serviceResource.getPath();

				apiDefDomain.setPackageHierachy(urlBuilder.toString() + packageHierachySecondPart);
				System.out.println("Package Hierachy String :" + apiDefDomain.getPackageHierachy());

				final Method method = (Method) methodObj;
				collectMethodInfo(apiDefDomain, method);

				apiDefDomain.setScanType(Integer.parseInt(StratergyType.STRATERGY_ID_REST));
				apiDefinitionSet.add(apiDefDomain);
				
			}

		}

	}



	private void collectMethodInfo(final ApiDefinition apiDefDomain, final Method method) {

		final String id = method.getId();
		System.out.println("  Id:" + id);

		apiDefDomain.setName(id);
	}

	public static ApiDefinitionParser getObject() {
		return new ApiDefinitionParser();
	}
}
